package com.example.base.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.base.excetion.GlobalExcetion;
import com.example.base.system.domain.SysDicCategory;
import com.example.base.system.domain.vo.SysDicCategoryVo;
import com.example.base.system.mapper.SysDicCategoryMapper;
import com.example.base.system.service.SysDicCategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 字典类别 服务实现类
 * </p>
 *
 * @author xiong
 * @since 2024-02-19
 */
@Service
@Transactional
@CacheConfig(cacheNames = "SysDicCategoryServiceImpl")
public class SysDicCategoryServiceImpl extends ServiceImpl<SysDicCategoryMapper, SysDicCategory> implements SysDicCategoryService {

    @Cacheable(cacheNames = "sysdiccategory",key = "#id")
    @Override
    public SysDicCategory getById(Serializable id){
        return super.getById(id);
    }

    @CacheEvict(cacheNames = "sysdiccategory", key = "#id")
    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @CacheEvict(cacheNames = "sysdiccategory", key = "#sysdiccategory.id")
    @Override
    public boolean updateById(SysDicCategory sysdiccategory) {
        return super.updateById(sysdiccategory);
    }

    @Override
    public SysDicCategory saveOrUpdate(SysDicCategoryVo vo) throws GlobalExcetion {
        SysDicCategory sysDicCategory=new SysDicCategory();
        BeanUtils.copyProperties(vo,sysDicCategory);
        if(vo.getId()!=null){
            SysDicCategory sysDicCategoryEntity=super.baseMapper.selectById(vo.getId());
            if(sysDicCategoryEntity==null){
                throw new GlobalExcetion(1,"数据不存在");
            }
            if(vo.getPid()!=0){
                SysDicCategory parent=super.getById(vo.getPid());
                if(parent==null){
                    throw new GlobalExcetion(1,"父级数据不存在");
                }
            }
            if(vo.getCategoryNo()!=null){
                if(!vo.getCategoryNo().equals(sysDicCategoryEntity.getCategoryNo())){
                    SysDicCategory no=getSysDicCategoryByNo(vo.getCategoryNo());
                    if(no!=null){
                        throw new GlobalExcetion(1,"分类编号已存在");
                    }
                }
            }
            sysDicCategory.setUpdatetime(new Date());
            super.baseMapper.updateById(sysDicCategory);
        }else {
            if(vo.getPid()!=0){
                SysDicCategory parent=super.getById(vo.getPid());
                if(parent==null){
                    throw new GlobalExcetion(1,"父级数据不存在");
                }
            }
            if(vo.getCategoryNo()!=null){
                SysDicCategory no=getSysDicCategoryByNo(vo.getCategoryNo());
                if(no!=null){
                    throw new GlobalExcetion(1,"分类编号已存在");
                }
            }
            sysDicCategory.setCreatetime(new Date());
            sysDicCategory.setUpdatetime(new Date());
            sysDicCategory.setDeleted(0);
            super.baseMapper.insert(sysDicCategory);
        }
        return sysDicCategory;
    }

    @CachePut(cacheNames = "sysdiccategory", key = "#sysdiccategory.id")
    public SysDicCategory saveSysDicCategory(SysDicCategory sysdiccategory) throws GlobalExcetion {
        super.save(sysdiccategory);
        return sysdiccategory;
    }

    @CacheEvict(cacheNames = "sysdiccategory", key = "#sysdiccategory.id")
    public SysDicCategory updateSysDicCategoryById(SysDicCategory sysdiccategory) throws GlobalExcetion{
        super.updateById(sysdiccategory);
        return sysdiccategory;
    }

    @Override
    public List<SysDicCategory> treeList() {
        List<SysDicCategory> list=super.list();
        return getTree(list);
    }

    @Override
    public SysDicCategory getSysDicCategoryByNo(String no) {
        LambdaQueryWrapper<SysDicCategory> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDicCategory::getCategoryNo,no);
        SysDicCategory sysDicCategory=super.baseMapper.selectOne(lambdaQueryWrapper);
        return sysDicCategory;
    }


    private static List<SysDicCategory> getTree(List<SysDicCategory> list){
        List<SysDicCategory> array=new ArrayList<>();
        for (SysDicCategory sysDicCategory : list) {
            if(sysDicCategory.getPid()!=null && sysDicCategory.getPid()==0){
                getTreeChild(sysDicCategory,list);
                array.add(sysDicCategory);
            }
        }
        return array;
    }

    private static void getTreeChild(SysDicCategory entity,List<SysDicCategory> list){
        for (SysDicCategory sysDicCategory : list){
            if(sysDicCategory.getPid() !=null && entity.getId().equals(sysDicCategory.getPid())){
                if(entity.getChildren()==null){
                    entity.setChildren(new ArrayList<>());
                }
                entity.getChildren().add(sysDicCategory);
                getTreeChild(sysDicCategory,list);
            }
        }
    }
}
